package com.gitee.ixtf.vertx.kotlinx

import cn.hutool.core.io.FileUtil
import cn.hutool.log.Log
import com.gitee.ixtf.core.kotlinx.*
import com.gitee.ixtf.vertx.nonLogT
import com.google.common.io.ByteStreams
import io.vertx.core.buffer.Buffer
import io.vertx.core.eventbus.Message
import io.vertx.core.http.HttpMethod
import io.vertx.core.http.RequestOptions
import io.vertx.core.json.JsonArray
import io.vertx.core.json.JsonObject
import java.io.File
import java.io.InputStream
import java.net.URI
import java.net.URL
import java.nio.file.Path

fun URL.requestOptions(method: HttpMethod = HttpMethod.POST) =
    RequestOptions().apply {
      val ssl = protocol.last() == 's'
      this.method = method
      host = this@requestOptions.host
      setSsl(ssl)
      setPort(this@requestOptions.port.takeIf { it > 0 } ?: if (ssl) 443 else 80)
      setURI(file)
    }

fun URI.requestOptions(method: HttpMethod = HttpMethod.POST) = toURL().requestOptions(method)

fun InputStream.jsonObject(): JsonObject = use { ByteStreams.toByteArray(this) }.jsonObject()

fun ByteArray.jsonObject(): JsonObject = JsonObject(Buffer.buffer(this))

fun ByteArray.jsonArray(): JsonArray = JsonArray(Buffer.buffer(this))

fun String.jsonObject() = Buffer.buffer(this).toJsonObject()

fun Path.jsonObject() = FileUtil.readBytes(this).jsonObject()

fun File.jsonObject() = FileUtil.readBytes(this).jsonObject()

fun String.jsonArray() = Buffer.buffer(this).toJsonArray()

fun Path.jsonArray() = FileUtil.readBytes(this).jsonArray()

fun File.jsonArray() = FileUtil.readBytes(this).jsonArray()

fun Buffer.gzip() = bytes.gzip()

fun Buffer.unGzip() = bytes.unGzip()

inline fun <reified T> Buffer.readJson(): T = bytes.readJson()

inline fun <reified T> Buffer.inputCommand(): T = bytes.inputCommand()

fun JsonObject.gzip() = toBuffer().gzip()

fun JsonObject.unGzip() = toBuffer().unGzip()

inline fun <reified T> JsonObject.inputCommand(): T = toBuffer().inputCommand()

fun Message<*>.failure(log: Log, t: Throwable, msg: String = address()) {
  t.rCause().let {
    fail(400, it.message)
    if (!nonLogT(t)) log.error(msg, it)
  }
}
